﻿using ServiceStack;
using ServiceStack.Auth;
using ServiceStack.Web;
using System.Collections.Generic;
using ServiceStack.OrmLite;
using AcexeService.Models;
using AcexeService.ServiceInterface.Lib;
using ServiceStack.Configuration;
using System.Text;
using System.Security.Cryptography;
using System;
using System.Web;

// 帮助文档
// https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization#custom-authentication-and-authorization

namespace AcexeService.ServiceInterface
{
    /// <summary>
    /// 自定义用户名和密码验证方式
    /// </summary>
    public class CustomCredentialsAuthProvider : CredentialsAuthProvider
    {
        public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
        {
            // 每次在客户端使用CustomCredentialsAuthProvider方式请求 [Authenticate] 的服务都会调用本方法
            // 需要找到使用 cookie 就能访问的办法

            // 如果 Session 有效，直接通过
            if (authService != null)
            {
                var loginsession = (CustomUserSession)authService.GetSession();
                if (loginsession.LoginSession != null)
                {
                    loginsession.LastModified = DateTime.Now;
                    return true;
                }
            }

            var dto = new LoginHelper().CheckLogin(new LoginModel()
            {
                LoginForm = new SYS_USER
                {
                    USERACCOUNT = userName,
                    USERPWD = password
                },
                LoginIp = System.Web.HttpContext.Current.Request.UserHostAddress,
                HttpHeader = System.Web.HttpContext.Current.Request.Headers["Referer"] + " , "
                           + System.Web.HttpContext.Current.Request.Headers["User-Agent"]
            });

            if (!dto.Flag)
            {

                throw new Exception(dto.Msg);
            }

            authService.GetSession().UserAuthName = userName;

            var dbFactory = new OrmLiteConnectionFactory(new AppSettings().GetString("AppDb"), SqlServerDialect.Provider);
            using (var db = dbFactory.Open())
            {
                var sysuser = db.Select<SYS_USER>(x => x.USERACCOUNT == userName)[0];
                authService.GetSessionBag().Set<SYS_USER>(sysuser);
            }

            return dto.Flag;
        }

        public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)
        {
            //let normal authentication happen
            var authResponse = (AuthenticateResponse)base.Authenticate(authService, session, request);

            //return your own class, but take neccessary data from AuthResponse
            //return new
            //{
            //    UserName = authResponse.UserName,
            //    SessionId = authResponse.SessionId,
            //    ReferrerUrl = authResponse.ReferrerUrl,
            //    SessionExpires = DateTime.Now
            //};
            return authResponse;
        }

        public override IHttpResult OnAuthenticated(IServiceBase authService,
            IAuthSession session, IAuthTokens tokens,
            Dictionary<string, string> authInfo)
        {
            //Fill IAuthSession with data you want to retrieve in the app eg:
            //session.FirstName = "some_firstname_from_db";

            //Call base method to Save Session and fire Auth/Session callbacks:
            return base.OnAuthenticated(authService, session, tokens, authInfo);

            //Alternatively avoid built-in behavior and explicitly save session with
            //authService.SaveSession(session, SessionExpiry);
            //return null;
        }
    }
}
